﻿#include <QEventLoop>
#include "MainWindow.h"
#include "qtimer.h"
#include "qpushbutton.h"
#include "./ui_MainWindow.h"
#include "once_trigger/utils/utils.h"
#include "libdaq/device/base_device.h"
#include "once_trigger/connect_page/connect_page.h"

using namespace libdaq::device;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow) {
    ui->setupUi(this);
    qRegisterMetaType<std::vector<std::vector<float> > >("std::vector<std::vector<float>>");
    // 创建设备
    base_device_ = NewDevice();
    connect(ui->Connnectbutton, &QPushButton::clicked, this, &MainWindow::ClickConnectAction);
    connect(ui->StartADCCollection, &QPushButton::clicked, this, &MainWindow::ClickStartADCCollectionAction);
    connect(ui->UpdateConfig, &QPushButton::clicked, this, &MainWindow::ClickUpdateConfig);
    connect(ui->OnceCollection, &QPushButton::clicked, this, &MainWindow::ClickSoftwareTrigger);
    connect(ui->StopADCCollection, &QPushButton::clicked, this, &MainWindow::ClickStopADCCollection);

    InitWaveWidget();
}

MainWindow::~MainWindow() {
    EndOnceCollection();
    delete ui;
}

void MainWindow::ConnectStatusSlot(bool status, ConnectPage::ConnectType type) {
    if (status) {
        connected_count++;
        if (!base_device_->InitializeDevice()) {
            qWarning(u8"初始化设备失败，请检查配置参数是否存在错误");
            return;
        }
        if (!base_device_->ConnectedDevice()) {
            qWarning(u8"发送连接设备命令失败");
            return;
        }

        // 延时确保配置正常下发
        QEventLoop loop;
        QTimer::singleShot(100, &loop, SLOT(quit()));
        loop.exec();
    } else{
        base_device_->DisconnectedDevice();
    }
}

void MainWindow::ClickConnectAction() {
    ConnectPage connect_page(base_device_, nullptr);
    // 初始化连接界面
    if (connect_page_.isNull()) {
        connect_page_.reset(new ConnectPage(base_device_));
        connect_page_->setModal(false);
        connect(connect_page_.get(), &ConnectPage::ConnectStatus, this, &MainWindow::ConnectStatusSlot);
    }
    connect_page_->InitParams(base_device_);
    connect_page_->raise();
    connect_page_->activateWindow();
    connect_page_->show();
}

void MainWindow::ClickStartADCCollectionAction() {
    if (connected_count == 0) {
        qWarning(u8"请先连接设备");
        return;
    }

    if (!is_start_adc_collection_) {
        // 开始采集
        is_start_adc_collection_ = true;
        
        // 清空波形
        base_wave_widget_->Clear();
        
        OnceCollection();
        qInfo(u8"启动ADC采集成功");
    }
}

void MainWindow::OnceCollection() {
    if (!is_start_adc_collection_) {
        return;
    }

    if (!base_device_->StopADCCollection()) {
        qWarning(u8"停止ADC采集失败");
        is_start_adc_collection_ = false;
        return;
    }

    EndOnceCollection();

    // 延时50ms
    QEventLoop loop;
    QTimer::singleShot(50, &loop, SLOT(quit()));
    loop.exec();

    if (!base_device_->StartADCCollection()) {
        qWarning(u8"启动ADC采集失败");
        is_start_adc_collection_ = false;
        return;
    }

    // 初始化数据缓冲区
    auto channel_count = base_device_->GetADCLegalChannelSize();
    adc_data_buffer_.resize(channel_count);
    for(auto& buffer : adc_data_buffer_) {
        buffer.clear();
    }

    // 获取启用的通道
    QVector<bool> channel_state = GetChannelEnabled();

    // 重置已完成线程计数
    completed_thread_count_ = 0;

    // 为每个启用的通道创建线程
    for(int i = 0; i < channel_state.size(); i++) {
        if(!channel_state.at(i)) {
            continue;
        }

        auto thread = QSharedPointer<OnceTriggerADCThread>::create(base_device_, i, adc_data_buffer_[i]);
        connect(thread.get(), &OnceTriggerADCThread::complete, this, &MainWindow::UpdatePlotData);
        once_trigger_adc_thread_list_.push_back(thread);
        thread->start();
    }
}

void MainWindow::EndOnceCollection() {
    for(int i = 0; i < once_trigger_adc_thread_list_.size(); i++) {
        auto& thread = once_trigger_adc_thread_list_[i];
        if(thread != nullptr) {
            thread->quit();
            thread->wait();
            thread = nullptr;
        }
    }
    once_trigger_adc_thread_list_.clear();
}

QVector<bool> MainWindow::GetChannelEnabled() {
    // 简化实现，默认使能全部通道
    // 在实际应用中应当读取用户界面上的通道勾选状态
    int channel_count = base_device_->GetADCLegalChannelSize();
    QVector<bool> channel_state(channel_count, true);
    return channel_state;
}

bool MainWindow::ConfigADCSampleRate() {
    // 采样率 1M
    if (!base_device_->ConfigADCSampleRate(libdaq::device::LockzhinerADCSampleRate::ADCSampleRate_1_M)) {
        qWarning(u8"采样率配置失败");
        return false;
    }
    return true;
}

bool MainWindow::ConfigADCChannel() {
    // 全通道使能
    if (!base_device_->ConfigADCChannel(0x03)) {
        qWarning(u8"ADC通道配置失败");
        return false;
    }
    return true;
}

bool MainWindow::ConfigADCTrigger() {
    uint32_t level = 0;
    auto type = static_cast<libdaq::device::LockzhinerADCTriggerType>(libdaq::device::LockzhinerADCTriggerType::DoubleEdge);
    auto mode = static_cast<libdaq::device::LockzhinerADCTriggerMode>(libdaq::device::LockzhinerADCTriggerMode::Single);
    auto channel = static_cast<libdaq::device::LockzhinerADCChannel>(libdaq::device::LockzhinerADCChannel::ADCChannelAINNone);
    if (!base_device_->ConfigADCTrigger(type, mode, channel, level)) {
        qWarning(u8"DAQ控制器配置ADC触发失败");
        return false;
    }
    return true;
}

void MainWindow::ClickUpdateConfig() {
    // 采样率配置
    ConfigADCSampleRate();
    
    // 电压量程 1V
    if (!base_device_->ConfigADCVoltage(libdaq::device::LockzhinerADCVoltage::ADCVoltage_10_V)) {
        qWarning(u8"电压量程配置失败");
    }
    
    // 通道使能
    ConfigADCChannel();
    
    // 触发配置
    ConfigADCTrigger();

    // 长度 4920个点
    if (!base_device_->ConfigADCTriggerLength(4920)) {
        qWarning(u8"触发长度配置失败");
    }
    
    // 超时 100ms
    if (!base_device_->ConfigTriggerTimeout(100)) {
        qWarning(u8"超时时间配置失败");
    }

    // 全通道DC
    if(!base_device_->ConfigACDC(0x03)){
        qWarning(u8"4通道DC配置失败");
    }

    qInfo(u8"下发配置成功");
}

void MainWindow::ClickSoftwareTrigger() {
    if(connected_count == 0) {
        qWarning(u8"请先连接设备");
        return;
    }
    
    if(!base_device_->ConfigADCTriggerSource
         (static_cast<uint8_t>(libdaq::device::DAQADCTriggerSource::TriggerSourceSoftware))){
        qWarning(u8"软件触发失败");
        return;
    }
    qInfo(u8"软件触发成功");
}

void MainWindow::ClickStopADCCollection() {
    if(!base_device_->StopADCCollection()){
        qWarning(u8"停止ADC采集失败");
        return;
    }
    
    is_start_adc_collection_ = false;
    EndOnceCollection();
    
    qInfo(u8"停止ADC采集成功");
}

void MainWindow::InitWaveWidget() {
    QVector<Qt::GlobalColor> channel_color_ = { // 通道颜色
        Qt::red, Qt::green
    };
    base_wave_widget_ = QSharedPointer<BaseWaveWidget>::create();
    base_wave_widget_->InitChannel(2, channel_color_);
    ui->stackedWidget->addWidget(base_wave_widget_.get());
    ui->stackedWidget->setCurrentWidget(base_wave_widget_.get());
}

void MainWindow::UpdatePlotData(int channel) {
    if (channel >= adc_data_buffer_.size() || adc_data_buffer_[channel].empty()) {
        return;
    }

    // 清空该通道数据并重新绘制
    base_wave_widget_->Clear(channel);

    // 添加数据到对应通道
    for (size_t j = 0; j < adc_data_buffer_[channel].size(); ++j) {
        base_wave_widget_->AddData(channel, adc_data_buffer_[channel][j]);
    }

    // 更新图表
    UpdateAutoScale();
    base_wave_widget_->replot(QCustomPlot::rpQueuedReplot);
    
    // 增加已完成线程计数并检查是否所有线程都已完成
    completed_thread_count_++;
    CheckAllThreadsFinished();
}

void MainWindow::UpdateAutoScale() {
    uint32_t data_length = base_device_->GetCurrentDataLength();
    base_wave_widget_->xAxis->setRange(0, data_length);
}

void MainWindow::CheckAllThreadsFinished() {
    // 获取启用的通道数量
    QVector<bool> channel_state = GetChannelEnabled();
    int enabled_channel_count = 0;
    for (bool enabled : channel_state) {
        if (enabled) {
            enabled_channel_count++;
        }
    }
    
    // 如果所有启用的通道都已完成采集，设置is_start_adc_collection_为false
    if (completed_thread_count_ >= enabled_channel_count && enabled_channel_count > 0) {
        is_start_adc_collection_ = false;
        qInfo(u8"所有通道采集完成");
    }
}

